package com.nio.page;

import android.animation.ObjectAnimator;
import android.content.Context;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.LinearLayout;

/**
 * Created by houlian.wang on 2016/11/29.
 */

public class NextevPagerView extends HorizontalScrollView{
    private static final String TAG = "NextevPagerView";
    private int baseScrollX;
    private int screenWidth;
    private float downRawX;
    private float downRawY;
    private float deltaRawX;
    private float deltaRawY;
    private boolean mDisallowIntercept;
    private LinearLayout containerLayout;
    private int deltaScrollX;
    private OnPageSelectedListener onPageSelectedListener;
    private OnPageScrollingListener onPageScrollingListener;
    public NextevPagerView(Context context, AttributeSet attrs) {
        super(context, attrs);
        DisplayMetrics displayMetrics = context.getResources().getDisplayMetrics();
        screenWidth = displayMetrics.widthPixels;
        deltaScrollX = screenWidth/2;
    }

    @Override
    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
        super.requestDisallowInterceptTouchEvent(disallowIntercept);
        Log.d(TAG, "disallowIntercept:" + disallowIntercept);
        this.mDisallowIntercept = disallowIntercept;
    }

    @Override
    public boolean shouldDelayChildPressedState() {
        return !mDisallowIntercept;
    }

    @Override
    public void computeScroll() {
        super.computeScroll();
        int currentPage = getCurrentPage();
        int scrollOffset = computeHorizontalScrollOffset();
        float currentOffset = (float) (scrollOffset*1.0/screenWidth);
        int newPage;
        float currentScroll, newScroll;
        if (currentPage == 0) {
            if (currentOffset > currentPage) {
                newPage = currentPage +1;
                Log.d(TAG, "currentPage1:" + currentPage + ",newPage1:" + newPage);
                newScroll = currentOffset - currentPage;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            } else {
                newPage = currentPage;
                Log.d(TAG, "currentPage2:" + currentPage + ",newPage2:" + newPage);
                newScroll = currentOffset - currentPage;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            }
        } else if (currentPage == getPageCount()-1) {
            if (currentOffset < currentPage) {
                newPage = currentPage - 1;
                Log.d(TAG, "currentPage3:" + currentPage + ",newPage3:" + newPage);
                newScroll = currentPage-currentOffset;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            } else {
                newPage = currentPage;
                Log.d(TAG, "currentPage4:" + currentPage + ",newPage4:" + newPage);
                newScroll = currentPage-currentOffset;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            }
        } else {
            if (currentOffset > currentPage) {
                newPage = currentPage +1;
                Log.d(TAG, "currentPage5:" + currentPage + ",newPage5:" + newPage);
                newScroll = currentOffset-currentPage;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            } else if (currentOffset < currentPage) {
                newPage = currentPage - 1;
                Log.d(TAG, "currentPage6:" + currentPage + ",newPage6:" + newPage);
                newScroll = currentPage-currentOffset;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            } else {
                newPage = currentPage;
                Log.d(TAG, "currentPage7:" + currentPage + ",newPage7:" + newPage);
                newScroll = currentOffset-currentPage;
                currentScroll = 1 - newScroll;
                if (onPageScrollingListener != null) {
                    onPageScrollingListener.onPageScrolling(currentPage, newPage, currentScroll, newScroll);
                }
            }
        }
    }

    public void addPage(View page, int index) {
        if (containerLayout == null) {
            containerLayout = (LinearLayout) getChildAt(0);
        }
        if (containerLayout != null) {
            LinearLayout.LayoutParams pageLayoutParams = new LinearLayout.LayoutParams(screenWidth, LinearLayout.LayoutParams.MATCH_PARENT);
            if (index == -1) {
                containerLayout.addView(page, pageLayoutParams);
            } else {
                containerLayout.addView(page, index, pageLayoutParams);
            }
        }
    }

    public void addPage(View page) {
        addPage(page, -1);
    }

    public View getPage(int index) {
        if (index < 0) {
            return containerLayout.getChildAt(0);
        } else if (index > getPageCount()) {
            return containerLayout.getChildAt(getPageCount() - 1);
        } else {
            return containerLayout.getChildAt(index);
        }
    }

    public void removePage(int index) {
        if (getPageCount() < 1) {
            return;
        }
        if (index < 0 || index > getPageCount()-1) {
            return;
        }
        containerLayout.removeViewAt(index);
    }

    public void removeAllPages() {
        if (getPageCount() > 0) {
            containerLayout.removeAllViews();
        }
    }

    public int getPageCount() {
        if (containerLayout != null) {
            return containerLayout.getChildCount();
        }
        return 0;
    }

    public int getCurrentPage() {
        return baseScrollX/screenWidth;
    }

    private int getBaseScrollX() {
        return getScrollX() - baseScrollX;
    }

    private void pagerScrollTo(int x) {
        //smoothScrollTo(x + baseScrollX, 0);
        pagerAnimation(x + baseScrollX);
        baseScrollX += x;
        Log.d(TAG, "baseScrollX:" + baseScrollX);
        if (onPageSelectedListener != null) {
            int index = baseScrollX/screenWidth;
            onPageSelectedListener.onPageSelected(index);
        }
    }

    public void pagerSelected(int index) {
        int scrollX = screenWidth*index;
        baseScrollX = scrollX;
        setScrollX(scrollX);
        if (onPageSelectedListener != null) {
            onPageSelectedListener.onPageSelected(index);
        }
    }

    public void pagerAnimation(int x) {
        ObjectAnimator pagerAnimation = ObjectAnimator.ofInt(this, "scrollX", x);
        pagerAnimation.setDuration(500);
        pagerAnimation.start();
    }

    @Override
    public boolean onTouchEvent(MotionEvent ev) {
        int action = ev.getAction();
        int scrollX = getBaseScrollX();
        int currentPage = getCurrentPage();
        switch (action) {
            case MotionEvent.ACTION_DOWN:
                downRawX = ev.getRawX();
                downRawY = ev.getRawY();
                Log.d(TAG,"DOWN ScrollOffset:" + computeHorizontalScrollOffset());
                break;
            case MotionEvent.ACTION_MOVE:
                deltaRawX = ev.getRawX() - downRawX;
                deltaRawY = ev.getRawY() - downRawY;
                /*if (getCurrentPage()==1) {
                    if (scrollX>0) {
                        return true;
                    }
                }*/
                break;
            case MotionEvent.ACTION_UP:
                if (scrollX > deltaScrollX) {
                    pagerScrollTo(screenWidth);
                } else if (scrollX > 0) {
                    pagerScrollTo(0);
                } else if (scrollX > - deltaScrollX) {
                    pagerScrollTo(0);
                } else {
                    pagerScrollTo(-screenWidth);
                }
                Log.d(TAG,"UP scrollX:" + baseScrollX);
                return true;
            case MotionEvent.ACTION_CANCEL:
                break;
        }
        return super.onTouchEvent(ev);
    }

    public void setOnPageSelectedListener(OnPageSelectedListener onPageSelectedListener) {
        this.onPageSelectedListener = onPageSelectedListener;
    }

    public void setOnPageScrollingListener(OnPageScrollingListener onPageScrollingListener) {
        this.onPageScrollingListener = onPageScrollingListener;
    }

    public interface OnPageSelectedListener{
        void onPageSelected(int index);
    }

    public interface OnPageScrollingListener{
        void onPageScrolling(int currentPage, int newPage, float currentScroll, float newScroll);
    }
}
